#include "cf_includes.h"

//================================================
CCF_Camera::CCF_Camera(void)
{
  Position = D3DXVECTOR3( 0, 0, -5 );
  Direction = D3DXVECTOR3( 0, 0, 1 );
  Up = D3DXVECTOR3( 0, 1, 0 );
}

//================================================
CCF_Camera::~CCF_Camera(void)
{
}
//================================================
void CCF_Camera::SetCamera( D3DXVECTOR3 pos, D3DXVECTOR3 dir, D3DXVECTOR3 up )
{
  Position = pos;
  D3DXVec3Normalize( &Direction, &dir );
  D3DXVec3Normalize( &Up, &up );
}
//================================================
void CCF_Camera::GoFront( double points )
{
  Position += points*Direction;
}
//================================================
void CCF_Camera::GoBack( double points )
{
  GoFront( -points );
}
//================================================
void CCF_Camera::GoLeft( double points )
{
  D3DXVECTOR3 vSide;
  D3DXVec3Cross( &vSide, &Direction, &Up );
  D3DXVec3Normalize( &vSide, &vSide );

  Position += points*vSide;
}
//================================================
void CCF_Camera::GoRight( double points )
{
  GoLeft( -points );
}
//================================================
void CCF_Camera::GoUp( double points )
{
  Position += points*Up;
}
//================================================
void CCF_Camera::GoDown( double points )
{
  GoUp( -points );
}
//================================================
void CCF_Camera::TurnLeft( double angle )
{
  //D3DXVECTOR3 vDirSide = sin( angle )*DEFAULT_UP_VECTOR;
  //D3DXVECTOR3 vUpSide = sin( angle )*DEFAULT_UP_VECTOR;
  D3DXVECTOR3 vDirSide = sin( angle )*Up;
  D3DXVECTOR3 vUpSide = sin( angle )*Up;

  D3DXVec3Cross( &vDirSide, &Direction, &vDirSide );
  D3DXVec3Cross( &vUpSide, &Up, &vUpSide );

  Direction = cos( angle )*Direction + vDirSide; 
  Up = cos( angle )*Up + vUpSide; 
}
//================================================
void CCF_Camera::TurnRight( double angle )
{
  TurnLeft( -angle );
}
//================================================
void CCF_Camera::TiltFront( double angle )
{
  D3DXVECTOR3 vSide;
  D3DXVec3Cross( &vSide, &Direction, &Up );

  D3DXVECTOR3 vSubDir = sin( angle )*vSide;
  D3DXVECTOR3 vSubUp = sin( angle )*vSide;

  D3DXVec3Cross( &vSubDir, &Direction, &vSubDir );
  D3DXVec3Cross( &vSubUp, &Up, &vSubUp );

  Direction = cos( angle )*Direction + vSubDir; 
  Up = cos( angle )*Up + vSubUp; 
}
//================================================
void CCF_Camera::TiltBack( double angle )
{
  TiltFront( -angle );
}
//================================================
void CCF_Camera::TiltLeft( double angle )
{
  /*D3DXVECTOR3 vSide = sin( angle )*Direction;
  D3DXVec3Cross( &vSide, &Up, &vSide );

  Direction = cos( angle )*Up + vSide; */
  
	D3DXVECTOR3 vDirSide = sin( angle )*Up;
  D3DXVec3Cross( &vDirSide, &Direction, &vDirSide );
  Direction = cos( angle )*Direction + vDirSide; 
}
//================================================
void CCF_Camera::TiltRight( double angle )
{
  TiltLeft( -angle );
}

//================================================
D3DXMATRIX* CCF_Camera::CalcViewMatrix()
{
  D3DXVECTOR3 target = Position + Direction;
  D3DXMatrixLookAtLH( &m_result, &Position, &target, &Up );

  return &m_result;
}
//================================================
D3DXMATRIX* CCF_Camera::CalcProjectionMatrix()
{
  D3DXMatrixPerspectiveFovLH( &m_projection, D3DX_PI / 4,  1.0f, 1.0f, 10000.0f );

  return &m_projection;
}
//================================================
D3DXMATRIX* CCF_Camera::CalcInvertViewMatrix()
{
  D3DXMatrixInverse( &m_invertView, NULL, &m_result );

  return &m_invertView;
}
